//-------------------------------------------------------------------
//	Copyright (c) 2012-2014 Zhirnov Andrey
//	This file is part of the "UXGEN-ES" project.
//	See copyright notice in "Engine.h".
//-------------------------------------------------------------------

#pragma once

#include "Platforms/Base/IApplication.h"

#if defined( PLATFORM_SDL )

#include "Platforms/SDL/SDLSensorManager.h"
#include "Platforms/SDL/SDLApplication.h"
//#include "Platforms/SDL/WWidgets.h"
#include "Base/Types/TimeProfiler.h"
#include "Graphics/GLES/opengles.h"


namespace Engine
{
namespace Platforms
{

	//
	// SDL Platform
	//

	class SDLPlatform : public IPlatform
	{
	// types
	private:
		enum EPause
		{
			NO_FOCUS	= 0x1,
			USER_PAUSE	= 0x2,
			ON_DESTROY	= 0x4,
		};
		
		typedef static_array< string, EDirectory::_COUNT >	directories_t;


	// variables
	protected:
		SDLSensorManager			_sensorManager;
		
		Ptr< IApplication >			_application;
		
		directories_t				_directories;

		TimeProfiler<uint64>		_timer;
		
		SDL_Window	*				_window;
		SDL_GLContext				_context;
		
		uint						_pause;

		ivec2						_windowSize;
		ivec2						_windowPos;
		SysEvent::time_t			_lastUpdateTime;

		bool						_isLooping;
		bool						_backgroundMode;
		bool						_requestQuit;

		EDevice::type				_requiredDeviceType;

		// widgets //
		//WindowsEditText				_editText;
		//WindowsWebView				_webView;


		static SDLPlatform *		_instance;


	// methods
	public:
		SDLPlatform ();
		~SDLPlatform ();

		virtual int  Loop ();

		virtual void SendEvent (const SysEvent &ev);
		virtual void SendEventDelayed (const SysEvent &ev);

		static Ptr< SDLPlatform >	GetInstance ()			{ return _instance; }

		EDevice::type				GetDeviceType () const	{ return _requiredDeviceType; }

		static void CreateInstance ();
		static void DestroyInstance ();


	protected:
		// events //
		virtual bool _Init ();
		virtual void _Quit ();
		virtual void _EnterForeground (bool completed);
		virtual void _EnterBackground (bool completed);
		virtual void _VisibilityChanged (bool isVisible);
		virtual void _OnResized (uint w, uint h);
		virtual void _OnMove (const ivec2 &delta) {}
		
		virtual void _OnKey (int keyCode, bool down);
		virtual void _OnTouch (int id, bool down, int x, int y);
		virtual void _OnTouchMotion (int id, int x, int y);


	protected:
		SysEvent::time_t	_GetTimestamp ()	{ return _timer.GetTimeDelta(); }

		bool _CreateWindow ();
		bool _InitOpenGL (INOUT VideoSettings &vs);
		void _Destroy ();

		bool _EventLoop ();
		void _ProcessEvents ();
		void _BackgroundLoop ();

		virtual void _Update (bool redraw);
		
		static void _SendEventDelayed (EventSystem *es, const SysEvent &ev);

		static uvec2		_GetScreenResolution ();


	// interface
	public:
		// Sensor //
		virtual bool EnableSensor (ESensor::type sensor) override						{ return _sensorManager.EnableSensor( sensor ); }
		virtual bool DisableSensor (ESensor::type sensor) override						{ return _sensorManager.DisableSensor( sensor ); }
		virtual bool IsSensorEnabled (ESensor::type sensor) override					{ return _sensorManager.IsSensorEnabled( sensor ); }
		virtual bool SetSensorUpdateRate (ESensor::type sensor, uint rate) override		{ return _sensorManager.SetSensorUpdateRate( sensor, rate ); }
		virtual bool HasSensor (ESensor::type sensor) override							{ return _sensorManager.HasSensor( sensor ); }

		// Render //
		virtual bool InitRender (INOUT VideoSettings &vs) override;
		virtual void SwapBuffers () override;
		virtual bool IsRenderingAvailable () override;
		
		// Widgets //
		virtual Ptr< IWidget >	GetWidget (IWidget::EType type) override;
		
		// Audio //
		virtual void EnableAudio (bool enabled) override;
		
		// Extensions //
		virtual Ptr< HardwareCamera > GetCamera () override								{ return null; }
		
		// License //
		virtual void CheckLicense (OnLicenseChecked_t callback, uni_c_string publicKey) override;

		// Other //
		virtual void Terminate () override;
		
		virtual void SendEmail (uni_c_string address, uni_c_string subject,
								uni_c_string text, uni_c_string attachment) override;

		virtual void SendSMS (uni_c_string number, uni_c_string text) override;
		virtual void PhoneCall (uni_c_string number) override;
		
		virtual void Vibrate (const uni_array<const int64> &pattern) override {}

		virtual void BackgroundMode (bool enabled) override;

		virtual void InitDevice (EDevice::type deviceType) override;
		virtual void SetDisplayOrientation (EDisplayOrientation::type orientation) override;
		
		virtual void OpenURL (uni_c_string url) override;

		virtual void ShowNotification (uni_c_string text, bool longTime) override;

		virtual void ShowMessage (const BaseObjectPtr &obj,
								  void (* callback) (const BaseObjectPtr &obj, int result),
								  uni_c_string caption, uni_c_string text,
								  uni_c_string positive, uni_c_string negative) override;

		virtual EventSystemPtr		GetEventSystem () override;
		virtual IParallelThreadPtr	GetThread ()	  override;
		
		virtual uni_c_string 		GetDirectoryPath (EDirectory::type type) override	{ return _directories[ type ]; }
	};


}	// Platforms
}	// Engine

#endif	// PLATFORM_SDL